package com.zhang.crm.filter;


import com.zhang.crm.constant.Constants;
import com.zhang.crm.pojo.TUser;
import com.zhang.crm.result.CodeEnum;
import com.zhang.crm.result.R;
import com.zhang.crm.service.RedisService;
import com.zhang.crm.util.JSONUtil;
import com.zhang.crm.util.JWTUtil;
import com.zhang.crm.util.ResponseUtil;
import jakarta.annotation.Resource;
import jakarta.servlet.FilterChain;
import jakarta.servlet.ServletException;
import jakarta.servlet.http.HttpServletRequest;
import jakarta.servlet.http.HttpServletResponse;
import org.springframework.security.authentication.UsernamePasswordAuthenticationToken;
import org.springframework.security.core.context.SecurityContextHolder;
import org.springframework.stereotype.Component;
import org.springframework.util.StringUtils;
import org.springframework.web.filter.OncePerRequestFilter;

import java.io.IOException;
import java.util.concurrent.TimeUnit;

@Component
public class JWTFilter extends OncePerRequestFilter {

    @Resource
    private RedisService redisService;
    @Override
    protected void doFilterInternal(HttpServletRequest request, HttpServletResponse response, FilterChain filterChain) throws ServletException, IOException {
        String requestURI = request.getRequestURI();
        if ("/login".equals(requestURI)) {
            filterChain.doFilter(request,response);
        }else {
            //获取前端的token
            String token = null;
            if ("/api/exportExcel".equals(requestURI) || "/api/chooseExportExcel".equals(requestURI)){
                token = request.getParameter("Authorization");
            }else {
                token = request.getHeader("Authorization");
            }
            if (!StringUtils.hasText(token)) {
                //jwt为空
                R r = R.FAIL(CodeEnum.LOGIN_FAIL_NO_LOGIN);
                //写到浏览器
                ResponseUtil.write(response, JSONUtil.toJSON(r));
                return;
            }
            //验证jwt
            if(!JWTUtil.verifyJWT(token)){
                R r = R.FAIL(CodeEnum.LOGIN_FAIL_JWT_ILLEGALITY);
                ResponseUtil.write(response, JSONUtil.toJSON(r));
                return;
            }

            //解析jwt
            String s = JWTUtil.parseJWT(token);
            TUser t = JSONUtil.toObj(s, TUser.class);
            Integer userId = t.getId();
                //查看redis中是否存在 【提前退出 以及伪造】
            String s1 = redisService.get(Constants.REDIS_JWT_KEY + userId);
            if (!StringUtils.hasText(s1)) {
                R r = R.FAIL(CodeEnum.LOGIN_FAIL_JWT_EXPIRED);
                ResponseUtil.write(response, JSONUtil.toJSON(r));
                return;
            }

                //是否相等
            if (!token.equals(s1)) {
                R r = R.FAIL(CodeEnum.LOGIN_FAIL_JWT_ILLEGALITY);
                ResponseUtil.write(response, JSONUtil.toJSON(r));
                return;
            }
            //续期
            String rememberMe = request.getHeader("rememberMe");
            if (Boolean.parseBoolean(rememberMe)){
                //记住我 续期七天
                redisService.expire(Constants.REDIS_JWT_KEY + userId, 7L, TimeUnit.DAYS);
            }else {
                redisService.expire(Constants.REDIS_JWT_KEY + userId, 30L, TimeUnit.MINUTES);
            }

            //全部验证通过
            UsernamePasswordAuthenticationToken usernamePasswordAuthenticationToken = new UsernamePasswordAuthenticationToken(t,null,t.getAuthorities());
            SecurityContextHolder.getContext().setAuthentication(usernamePasswordAuthenticationToken);

            filterChain.doFilter(request,response);
        }


    }
}
